package com.ptone.messageCenter.common.utils;


import com.ptone.messageCenter.common.enums.Enums;
import org.apache.commons.lang.time.FastDateFormat;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.Optional;

/**
 * @Author Yuanhk
 * @Date 2020/11/9 11:09
 */
public class TimeUtil {
    public static String timeFormat = "yyyy-MM-dd HH:mm:ss";
    public static String timeWithOutSecondFormat = "yyyy-MM-dd HH:mm";
    private static String millisecondFormat = "yyyy-MM-dd HH:mm:ss SSS";
    private static String dateFormat = "yyyy-MM-dd";
    private static String zoneId = "+8";

    public static final FastDateFormat ISO_TIME_FORMAT = FastDateFormat.getInstance(timeFormat);

    public static ZoneId getZoneId() {
        //return getZoneId()
        return ZoneId.of(zoneId);
    }

    public static ZoneOffset getZoneOffset() {
        return ZoneOffset.of(zoneId);
    }

    /**
     * LocalDateTime转时间戳 单位：毫秒
     *
     * @param time
     * @return
     */
    public static long toEpochMilli(LocalDateTime time) {
        return time.atZone(getZoneId()).toInstant().toEpochMilli();
    }

    /**
     * LocalDateTime转时间戳 单位：秒
     *
     * @param time
     * @return
     */
    public static long toEpochSecond(LocalDateTime time) {
        return time.toEpochSecond(getZoneOffset());
    }


    private static LocalDateTime getStartDate(LocalDateTime time, Integer period) {
        if (period == Enums.Period.MONTH.code)
            return time.with(TemporalAdjusters.firstDayOfMonth());
        else if (period == Enums.Period.YEAR.code)
            return time.with(TemporalAdjusters.firstDayOfYear());
        return time;
    }

    private static LocalDateTime getEndDate(LocalDateTime time, Integer period) {
        if (period == Enums.Period.MONTH.code)
            return time.with(TemporalAdjusters.lastDayOfMonth());
        else if (period == Enums.Period.YEAR.code)
            return time.with(TemporalAdjusters.lastDayOfYear());
        return time;
    }

    public static LocalDateTime getStartTime(LocalDateTime time, Integer period) {
        return getStartDate(time, period).withHour(0).withMinute(0).withSecond(0).withNano(0);
    }

    public static LocalDateTime getEndTime(LocalDateTime time, Integer period) {
        return getEndDate(time, period).withHour(23).withMinute(59).withSecond(59).withNano(999);
    }

    public static LocalDateTime getNow() {
        return LocalDateTime.now(getZoneId());
    }

    /**
     * Date 转 LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), getZoneId());
    }

    /**
     * 时间戳转 LocalDateTime
     *
     * @param remindTime
     * @return
     */
    public static LocalDateTime toLocalDateTime(Long remindTime) {
        return Optional.ofNullable(remindTime)
                .map(t -> LocalDateTime.ofEpochSecond(remindTime, 0, getZoneOffset()))
                .orElse(null);
    }

    /**
     * LocalDateTime 转 Date
     *
     * @param localDateTime
     * @return
     */
    public static Date toDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(getZoneId()).toInstant());
    }

    public static Date asDate(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay().atZone(getZoneId()).toInstant());
    }

    public static LocalDate asLocalDate(Date date) {
        return Instant.ofEpochMilli(date.getTime()).atZone(getZoneId()).toLocalDate();
    }

    public static LocalDateTime asLocalDateTime(Date date) {
        return Instant.ofEpochMilli(date.getTime()).atZone(getZoneId()).toLocalDateTime();
    }


    /**
     * 时间格式化
     *
     * @param localDateTime
     * @return
     */
    public static String formatTime(LocalDateTime localDateTime) {
        return localDateTime.format(DateTimeFormatter.ofPattern(timeFormat));
    }

    public static LocalDateTime parseTime(String s) {
        return LocalDateTime.parse(s, DateTimeFormatter.ofPattern(timeFormat));
    }

    public static String formatMillisecond(LocalDateTime localDateTime) {
        return localDateTime.format(DateTimeFormatter.ofPattern(millisecondFormat));
    }

    public static String formatDate(Date date) {
        return ISO_TIME_FORMAT.format(date);
    }

    public static String formatDate(LocalDateTime localDateTime) {
        return localDateTime.format(DateTimeFormatter.ofPattern(timeFormat));
    }

    public static String formatDate(LocalDate localDate) {
        return localDate.format(DateTimeFormatter.ofPattern(dateFormat));
    }

    public static String getDateTimeNow() {
        return TimeUtil.getNow().toString().replace("T", " ");
    }
}
